package com.itheima.es;

import com.alibaba.fastjson.JSON;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * 搜索文档的API
 * @作者 itcast
 * @创建日期 2020/11/29 9:31
 **/
public class EsDemo03 {
    RestHighLevelClient restHighLevelClient;


    /**
     * note:字段中  包含 唱歌javaee 的文档数据
     */
    @Test
    public void matchDocument() throws IOException {
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // 构建一个match条件
        builder.query(QueryBuilders.matchQuery("note","唱歌javaee"));
        // 执行该条件 打印结果
        printDocumentResult(builder);
    }
    /**
     * 性别为女的所有同学
     */
    @Test
    public void termDocument() throws IOException {
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // 构建一个match条件
        builder.query(QueryBuilders.termQuery("gender","0"));
        // 执行该条件 打印结果
        printDocumentResult(builder);
    }
    /**
     * 查询 年龄在22到28之间的所有同学
     */
    @Test
    public void rangeDocument() throws IOException {
        SearchSourceBuilder builder = new SearchSourceBuilder();
//        QueryBuilders.rangeQuery("age").gte(22).lte(28);
        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
        rangeQuery.gte(22);
        rangeQuery.lte(28);
        builder.query(rangeQuery);
        // 执行该条件 打印结果
        printDocumentResult(builder);
    }
    /**
     * 查询 文档note字段中  包含 同学
     * 并且 性别为 1
     * 并且 年龄小于 26岁
     */
    @Test
    public void boolDocument() throws IOException {
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // 构建一个bool的条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        // * 查询 文档note字段中  包含 同学
        boolQueryBuilder.must(QueryBuilders.matchQuery("note","同学"));
        // * 并且 性别为 1
        boolQueryBuilder.filter(QueryBuilders.termQuery("gender","1"));
        // * 并且 年龄小于 26岁
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").lt(26));
        builder.query(boolQueryBuilder);
        // 执行该条件 打印结果
        printDocumentResult(builder);
    }

    /**
     * 查询全部文档数据
     */
    @Test
    public void matchAllDocument() throws IOException {
        // 1. 创建搜索请求   SearchRequest
        SearchRequest request = new SearchRequest("user");
        //   构建整体参数的对象  SearchSourceBuilder
        SearchSourceBuilder builder = new SearchSourceBuilder();
        //      builder.query  提供查询条件工具类  QueryBuilders
        MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
        builder.query(matchAllQuery);
        //      builder.sort
        //      builder.from + size
        //      builder.highlight
        //      builder.aggs
        // 调用searchRequest.source(builder);
        request.source(builder);
        // 2. 客户端执行搜索请求  client.search
        SearchResponse searchResponse = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        // 3. 解析响应结果   SearchResponse
        // response.getHits
        SearchHits hits = searchResponse.getHits(); // 查询结果
        // .getToTalHits().value 查询结果总数量
        System.out.println("查询结果数量:" + hits.getTotalHits().value);
        // .getHits  得到文档列表
        SearchHit[] docList = hits.getHits();
        //      遍历文档列表
        for (SearchHit searchHit : docList) {
            //          .getSource 获取文档内容
            String userJson = searchHit.getSourceAsString();
            User user = JSON.parseObject(userJson,User.class);
            System.out.println(user);
        }
            //          .getHighligher 获取高亮处理结果
        // response.getAggregations 获取聚合结果
    }

    /**
     * 将通用的代码封装
     * 外部只需要构建builder条件 传入即可
     * @param builder
     * @throws IOException
     */
    public void printDocumentResult(SearchSourceBuilder builder) throws IOException {
        // 1. 创建搜索请求   SearchRequest
        SearchRequest request = new SearchRequest("user");
        request.source(builder);
        // 2. 客户端执行搜索请求  client.search
        SearchResponse searchResponse = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        // 3. 解析响应结果   SearchResponse
        // response.getHits
        SearchHits hits = searchResponse.getHits(); // 查询结果
        // .getToTalHits().value 查询结果总数量
        System.out.println("查询结果数量:" + hits.getTotalHits().value);
        // .getHits  得到文档列表
        SearchHit[] docList = hits.getHits();
        //      遍历文档列表
        for (SearchHit searchHit : docList) {
            //          .getSource 获取文档内容
            String userJson = searchHit.getSourceAsString();
            User user = JSON.parseObject(userJson,User.class);
            System.out.println(user);
        }
        //          .getHighligher 获取高亮处理结果
        // response.getAggregations 获取聚合结果
    }





    @Before
    public void init(){
        restHighLevelClient = new RestHighLevelClient(
                RestClient.builder(
                        // 要连接的es地址
                        new HttpHost("192.168.200.150",9200,"http")
//                        new HttpHost("192.168.200.151",9200,"http"),   // 如果是集群的话可以写多个
//                        new HttpHost("192.168.200.152",9200,"http")
                )
        );
    }
    @After
    public void close() throws IOException {
        restHighLevelClient.close();
    }
}
